//
// Created by ct on 2020/10/30.
//

#include "nettop_run.h"

namespace nettop {




    char    curses_setup::BPS[] = "Byte/s",
            curses_setup::KBPS[] = "KiB/s ",
            curses_setup::MBPS[] = "MiB/s ",
            curses_setup::GBPS[] = "GiB/s ";

    void curses_setup::redraw(const std::chrono::nanoseconds &tm_elapsed, nettop::ps_vec &ps_v,
                              const nettop::proc_mgr::stats &st) {
        for (const auto &i : ps_v) {
            std::string r_cmd = i.cmd;
            double r_d = 0.0;
            double s_d = 0.0;
            const char *fmt = "";
            recv_send_format(tm_elapsed, i.total_rs.first, i.total_rs.second, r_d, s_d, fmt);
            printf("%6d  %10.2f %10.2f  %-5s \n", i.pid, r_d, s_d, fmt);
        }
    }

    std::string curses_setup::format_proc(const std::chrono::nanoseconds &tm_elapsed, nettop::ps_vec &ps_v,
                                          const nettop::proc_mgr::stats &st) {
        std::string str("{\"data\":[");
        int l = ps_v.size();
        for (const auto &i : ps_v){
            std::string r_cmd  = i.cmd;
            double r_d = 0.0 , s_d = 0.0;
            const char * fmt = "";
            recv_send_format(tm_elapsed, i.total_rs.first, i.total_rs.second, r_d, s_d, fmt);

            str += "{";
            str += "\"pid\":";
            str += std::to_string(i.pid);
            str += ",";
            str += "\"cmd\":";
            str += "\""+i.cmd.substr(0,40) +"\"";
            str += ",";
            str += "\"rd\":";
            str += std::to_string(r_d);
            str += ",";
            str += "\"sd\":";
            str += std::to_string(s_d);
            str += ",";
            str += "\"fmt\":";
            str += "\"";
            str += fmt;
            str += "\"";
            str += "}";
            if ( l-- == 1) {
                break;
            } else {

                str += ",";
            }
        }
        str += "]}";
        return str;
    }

    void curses_setup::recv_send_format(const std::chrono::nanoseconds &tm_elapsed, const size_t recv,
                                        const size_t sent, double &recv_d, double &sent_d, const char *&fmt) {
        const double tm_fct = 1000000000.0 / tm_elapsed.count();
        const size_t max_bytes = tm_fct * ((recv > sent) ? recv : sent);
        if (max_bytes >= 1024 * 1024 * 1024) {
            const double cnv_fct = 1.0 / (1024.0 * 1024.0 * 1024.0);
            recv_d = cnv_fct * recv * tm_fct;
            sent_d = cnv_fct * sent * tm_fct;
            fmt = GBPS;
        } else if (max_bytes >= 1024 * 1024) {
            const double cnv_fct = 1.0 / (1024.0 * 1024.0);
            recv_d = cnv_fct * recv * tm_fct;
            sent_d = cnv_fct * sent * tm_fct;
            fmt = MBPS;
        } else if (max_bytes >= 1024) {
            const double cnv_fct = 1.0 / 1024.0;
            recv_d = cnv_fct * recv * tm_fct;
            sent_d = cnv_fct * sent * tm_fct;
            fmt = KBPS;
        } else {
            recv_d = tm_fct * recv;
            sent_d = tm_fct * sent;
            fmt = BPS;
        }
    }


    nettop_mgr & nettop_mgr::Instance() {
        static nettop_mgr the_nettop_mgr;
        return the_nettop_mgr;
    }
}